import React, { useState, useImperativeHandle, useRef, Fragment } from "react";
import { message, TableProps, PaginationProps } from 'antd';
import { createStyles } from "antd-style";
import deepmerge from "deepmerge";

import Header from "./Header";
import Content from "./Content";
import Footer from "./Footer";
import { useFetchList } from './useProTable';
import { IProTableProps, IProTableRef } from "./typing";
import {
  ColumnProps as ColumnPropsAlias,
  ColumnsType as ColumnsTypeAlias,
  ColumnType as ColumnTypeAlias,
  ColumnGroupType as ColumnGroupTypeAlias,
  TablePaginationConfig as TablePaginationConfigAlias,
} from "antd/es/table";

export * from './typing';

export declare namespace TableType {
  type ColumnProps<T = any> = ColumnPropsAlias<T>;
  type ColumnsType<T = any> = ColumnsTypeAlias<T>;
  type ColumnType<T = any> = ColumnTypeAlias<T>;
  type ColumnGroupType<T = any> = ColumnGroupTypeAlias<T>;
  type TablePaginationConfig = TablePaginationConfigAlias;
}

const ProTableReal = React.forwardRef<IProTableRef, IProTableProps>(({ rowKey, fetchListDeps, dataAction, onError, theme, headerProps, contentProps, footerProps }, ref) => {
  const { styles } = useStyle();
  const headerHeight = headerProps.isShow ? theme.headerHeight : 0;
  const footerHeight = footerProps.isShow ? theme.footerHeight : 0;
  const headerRef = useRef<{ getHeaderData: () => Promise<{ filter: any }> }>();
  const [selected, setSelected] = useState<{ selectedRowKeys: string | number[], selectedRows: any[] }>({ selectedRowKeys: [], selectedRows: [] });
  const [allFilter, setAllFilter] = useState<{ filter: any, pagination: PaginationProps }>({ filter: {}, pagination: footerProps.pagination });

  const { fetching, data, doFetchList } = useFetchList(dataAction.fetchList, rowKey, allFilter, onError, headerRef, footerProps.isShow, fetchListDeps);
  const clearSelected = () => setSelected({ selectedRowKeys: [], selectedRows: [] });

  useImperativeHandle(ref, () => ({
    doFetchList,
    clearSelected,
  }))

  const innerTableProps: TableProps<any> = {
    // @ts-ignore
    rowSelection: { selectedRowKeys: selected.selectedRowKeys, onChange: (selectedRowKeys, selectedRows) => setSelected({ selectedRowKeys, selectedRows }) }
  }

  // 是否隐藏行checkbox
  const isHideRowSelection = (headerProps.operatorProps.btnList || []).filter(item => ["edit", "delete"].includes(item.innerType)).length == 0
  if (!headerProps.isShow || !contentProps.isShowRowSelection || isHideRowSelection) {
    delete innerTableProps.rowSelection;
  }

  return (
    <div className={styles.skProTable}>
      {headerProps.isShow && <Header
        ref={headerRef}
        height={headerHeight}
        filter={allFilter.filter}
        onError={onError}
        dataAction={dataAction}
        doFetchList={doFetchList}
        setFilter={(filter) => setAllFilter({ filter, pagination: { ...allFilter.pagination, current: 1 } })}
        selectedRowKeys={selected.selectedRowKeys}
        selectedRows={selected.selectedRows}
        clearSelected={clearSelected}
        theme={theme}
        {...headerProps}
      />}

      {contentProps.isShow && <Content
        headerHeight={headerHeight}
        footerHeight={footerHeight}
        loading={fetching}
        dataSource={footerProps.isShow ? ((data as { total: number, list: any[] }).list || []) : data as any[]}
        {...innerTableProps}
        {...{ ...contentProps.tableProps, rowKey: (record: any) => record[rowKey] }}
        Empty={contentProps.Empty}
      />}

      {footerProps.isShow && <Footer {...{
        height: footerHeight,
        total: (data as { total: number, list: any[] }).total,
        theme,
        ...allFilter.pagination,
        setPagination: (pagination) => {
          setAllFilter({ ...allFilter, pagination })
        },
      }} />}

      
    </div>
  )
})

export const ProTable = React.forwardRef<IProTableRef, IProTableProps>((props, ref) => {
  const [messageApi, messageContextHolder] = message.useMessage()
  const nextProps = deepmerge({
    rowKey: "id",
    fetchListDeps: [],
    onError: (errorMsg: string) => {
      messageApi.error(errorMsg, 3);
    },
    theme: {
      headerHeight: 40,
      footerHeight: 40,
      headerBgColor: "#fafafa",
      // headerBgColor: "#243d5d",
      headerBoxShadow: "0px 1px 6px #333333",
      footerBgColor: "#fafafa",
      // footerBgColor: "#243d5d",
      footerBoxShadow: "0px 1px 6px #333333",
    },
    headerProps: {
      isShow: true,
      operatorProps: {
        btnList: [
          {
            innerType: "create"
          },
          {
            innerType: "edit"
          },
          {
            innerType: "delete"
          },
          // {
          //     innerType: "copy"
          // }
        ]
      }
    },
    contentProps: {
      isShow: true,
      isShowRowSelection: true,
    },
    footerProps: {
      isShow: true,
      pagination: {
        current: 1,
        pageSize: 20,
      },
    }
  }, props);

  // @ts-ignore
  nextProps.headerProps.operatorProps.btnList = props.headerProps.operatorProps.btnList || nextProps.headerProps.operatorProps.btnList;

  return <Fragment>
    <ProTableReal ref={ref} {...nextProps} />
    {messageContextHolder}
  </Fragment>
})

// export default ProTable;

const useStyle = createStyles(({ css }) => ({
  skProTable: css`
    width: 100%;
    height: 100%;
    overflow: hidden;
  `
}))
